package com.xinghou.platform.dao.main.aspect;

import com.xinghou.platform.dao.bases.util.StringUtils;
import com.xinghou.platform.dao.main.common.DBUserInviteCached;
import com.xinghou.platform.model.main.UserInvite;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Tuple;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Aspect
@Component
public class UserInviteCacheAspect extends DBUserInviteCached {


    @Pointcut("execution(public * com.xinghou.platform.dao.main.UserInviteDAO.addUserInvite(..))")
    public void addUserInvite(){
    }

    @Pointcut("execution(public * com.xinghou.platform.dao.main.UserInviteDAO.getUserInviteRank(..))")
    public void getUserInviteRank(){
    }

    @Pointcut("execution(public * com.xinghou.platform.dao.main.UserInviteDAO.getIndexAndScoreByUser(..))")
    public void getIndexAndScoreByUser(){
    }


    @Around("addUserInvite()")
    public void addUserInvite(ProceedingJoinPoint pjp) throws Throwable{
        UserInvite userInvite = (UserInvite)((Object[])pjp.getArgs())[0];
        String setkey =CACHE_USERINVITE_SET;
        getRedisClient().zincrby(setkey, 1, userInvite.inviteuid+ "", CACHED_USERINVITE_DB_INDEX);
        pjp.proceed();
    }

    @Around("getUserInviteRank()")
    public List<UserInvite> getUserInviteRank(ProceedingJoinPoint pjp) throws Throwable{
        List<UserInvite> resultList = new ArrayList<UserInvite>();
        Integer userid  = (Integer)((Object[]) pjp.getArgs())[0];
        String setkey =CACHE_USERINVITE_SET;
        if(!getRedisClient().exists(setkey,CACHED_USERINVITE_DB_INDEX)){
           List<UserInvite> list = (List<UserInvite> ) pjp.proceed();
            for(UserInvite userInvite : list) {
                getRedisClient().zadd(setkey,userInvite.getScore(),String.valueOf(userInvite.getInviteuid()),CACHED_USERINVITE_DB_INDEX);
            }
        }
            Long index = getRedisClient().zrevrank(setkey, String.valueOf(userid), CACHED_USERINVITE_DB_INDEX);
             Set<Tuple>  set;
            if(index!=null &&index >10) {
                 set = getRedisClient().zrevrangeWithScores(setkey, index - 10, index+10, CACHED_USERINVITE_DB_INDEX);
                index =index-10;
            }else{
                 set = getRedisClient().zrevrangeWithScores(setkey, 0, 19, CACHED_USERINVITE_DB_INDEX);
                //zrangeByScoreWithScores
            }
         listAdd(resultList,set,index==null?null:index.intValue());
        return resultList;
    }




    @Around("getIndexAndScoreByUser()")
    public UserInvite getIndexAndScoreByUser(ProceedingJoinPoint pjp) throws Throwable{
        Integer userid  = (Integer)((Object[]) pjp.getArgs())[0];
        String setkey =CACHE_USERINVITE_SET;
        if(!getRedisClient().exists(setkey,CACHED_USERINVITE_DB_INDEX)){
            List<UserInvite> list = (List<UserInvite> ) pjp.proceed();
            for(UserInvite userInvite : list) {
                getRedisClient().zadd(setkey,userInvite.getScore(),String.valueOf(userInvite.getInviteuid()),CACHED_USERINVITE_DB_INDEX);
            }
        }
        Long index = getRedisClient().zrevrank(setkey, String.valueOf(userid), CACHED_USERINVITE_DB_INDEX);

        Double score = getRedisClient().zscore(setkey, String.valueOf(userid), CACHED_USERINVITE_DB_INDEX);
        UserInvite userInvite = new UserInvite();

        if(index!=null){
            userInvite.setIndex(index.intValue()+1);
            userInvite.setScore(score.intValue());
        }
        return userInvite;
    }

    public void listAdd(List<UserInvite> list,Set<Tuple> set,Integer index) {
        if(null==index){
            index =0;
        }

        for (Tuple tuple : set) {
            index++;
            UserInvite userInvite = new UserInvite();
            if (StringUtils.isNullOrEmpty(tuple.getElement())) {
                continue;
            }
            userInvite.setIndex(index);
            userInvite.setInviteuid(Integer.parseInt(tuple.getElement()));
            userInvite.setScore(Double.valueOf(tuple.getScore()).intValue());
            list.add(userInvite);

        }
    }
}
